package echecs;

import echecs.Pieces.Piece;
import static echecs.Pieces.Piece.*;

public class Etat implements Echiquier {

    boolean prise_en_passant;
    Couleur _couleur;
    int pIndexDepart;
    int pIndexArrivee;
    Piece pPieceDepart;
    int pDistance;
    int pIndexDirection;
    Piece[] PIECES;
    boolean _examineEchecs;

    public class Coups {

        int pIndexDepart;
        Piece pPieceDepart;
        int pIndexArrivee;

        public Coups(int pIndexDepart, Piece pPieceDepart, int pIndexArrivee) {
            this.pIndexDepart = pIndexDepart;
            this.pPieceDepart = pPieceDepart;
            this.pIndexArrivee = pIndexArrivee;
        }
    }
    Action InitialiseDistance = new Action() {

        public void exec() {
            pDistance = 1;
        }
    };
    Action InitialiseDirection = new Action() {

        public void exec() {
            pIndexDirection = 0;
        }
    };
    Action DistanceSuivante = new Action() {

        public void exec() {
            pDistance++;
        }
    };
    Action DirectionSuivante = new Action() {

        public void exec() {
            pIndexDirection++;
        }
    };
    Action LirePieceCaseDepart = new Action() {

        public void exec() {
            pPieceDepart = PIECES[pIndexDepart];
        }
    };
    Action CaseSuivante = new Action() {

        @Override
        public void exec() {
            pIndexDepart++;
        }
    };
    Predicat ExamineEchecs = new Predicat(){


        @Override
        public boolean eval() {
           return _examineEchecs;
        }

    };
    Predicat CaseArriveeOccupee = new Predicat() {

        @Override
        public boolean eval() {
            return indexArrivee() != -1 && PIECES[indexArrivee()] != null;
        }
    };
    Predicat CaseArriveeVide = new Predicat() {

        @Override
        public boolean eval() {
            return indexArrivee() != -1 && PIECES[indexArrivee()] == null;
        }
    };
    Predicat PiecesCouleursOpposees = new Predicat() {

        @Override
        public boolean eval() {
            return pPieceDepart.getCouleur() != PIECES[indexArrivee()].getCouleur();
        }
    };
    Predicat EstUnPionAuDepart = new Predicat() {

        @Override
        public boolean eval() {
            return Case.valeur(pIndexDepart).estARangee2() && pPieceDepart.getCouleur() == Couleur.BLANC ||
                    Case.valeur(pIndexDepart).estARangee7() && pPieceDepart.getCouleur() == Couleur.NOIR;
        }
    };
    Predicat PieceFouTourOuDame = new Predicat() {

        @Override
        public boolean eval() {
            return pPieceDepart.estFouTourOuDame();
        }
    };
    Predicat EstUnPion = new Predicat() {

        @Override
        public boolean eval() {
            return pPieceDepart.equals(PION_BLANC) || pPieceDepart.equals(PION_NOIR);
        }
    };
    Predicat AutreDirectionExiste = new Predicat() {

        @Override
        public boolean eval() {
            return pIndexDirection < pPieceDepart.getDeplacement().length;
        }
    };
    Predicat NouvelleCase = new Predicat() {

        @Override
        public boolean eval() {
            return pIndexDepart < NB_COLONNES * NB_RANGEES;
        }
    };
    Predicat PieceCouleurQuiJoue = new Predicat() {

        @Override
        public boolean eval() {
            return pPieceDepart != null && pPieceDepart.getCouleur() == _couleur;
        }
    };

    public Etat() {
    }

    public Etat(int pIndexDepart, Piece pPieceDepart, int pDistance, int pIndexDirection) {

        this.pIndexDepart = pIndexDepart;
        this.pPieceDepart = pPieceDepart;
        this.pDistance = pDistance;
        this.pIndexDirection = pIndexDirection;


    }

    protected int indexArrivee() {
        return ECHIQUIER[TO_ECHIQUIER[pIndexDepart] +
                pDistance * pPieceDepart.getDeplacement()[pIndexDirection]];
    }
}
